//Pitää kirjaa pelissä olevista palikoista yms, muutosten tarkkailu, INPUT

//-BlockReservoir kaikkia pelissä olevia mahdollisia luotavia palikoita varten
//CollisionDetection
import java.util.concurrent.CopyOnWriteArrayList;

public class Game {

  boolean started;
  int endFrame;
  
  Team teamLeft;
  Team teamRight;

  Table table;

  int noMansLandSize;
  //middle of no man's land
  int noMansLandPosition;

  //size of player made blocks
  int blockSize;
  
  BlockFactory blockFactory;
  
  //list of template blocks that player-created blocks are compared to
  ArrayList<Block> blockTemplates;  
  
  //list of blocks currently being made by players
  ArrayList<Block> blocksTeamA;
  ArrayList<Block> blocksTeamB;
  
  //list of blocks that teams have made
  CopyOnWriteArrayList<Block> completedBlocks;
 
  Game() {
    teamLeft = new Team();
    teamRight = new Team();
    noMansLandSize = (int)(width * 0.1);
    blockSize = 250;
    endFrame = -endMsgLength;
    started = false;
  }
  
  void end() {
    started = false;
    this.endFrame = frameCount;
  }
  
  void start() { 
    this.noMansLandPosition = (int)width/2;
    this.blockFactory = new BlockFactory();
    this.completedBlocks = new CopyOnWriteArrayList();
    this.blockTemplates = new ArrayList();
    this.initializeTemplates();
    teamRight.score = 0;
    teamLeft.score = 0;
    blocksTeamA = new ArrayList();
    blocksTeamB = new ArrayList();
    started = true;
  }
 
  void setUI(Table table) {
     this.table = table;
  } 

  void initializeTemplates() {
    //add template blocks
    
    Block template = this.blockFactory.createRandom();
    template.translate(width/2, 140);
    this.blockTemplates.add(template);

    template = this.blockFactory.createUniqueRandom(this.blockTemplates);
    template.translate(width/2, 400);
    this.blockTemplates.add(template);
    
    template = this.blockFactory.createUniqueRandom(this.blockTemplates);
    template.translate(width/2, height-400);
    this.blockTemplates.add(template);
    
    template = this.blockFactory.createUniqueRandom(this.blockTemplates);
    template.translate(width/2, height-140);
    this.blockTemplates.add(template);
  }
  
  //dunno what this is
  void updateNoMansLandPosition() {
    noMansLandPosition = (int)(width/2 + (-teamLeft.score/(teamLeft.score+teamRight.score) + teamRight.score/(teamLeft.score+teamRight.score))*width);
    println(noMansLandPosition);
  }
  
  // Returns all incomplete blocks (both teams)
  ArrayList<Block> getIncompleteBlocks() {
    ArrayList<Block> blocks = new ArrayList(this.blocksTeamA);
    blocks.addAll(this.blocksTeamB);
    return blocks;
  }
  
  void frameUpdate() {
    //move block from blocksTeamA to completedBlocks if similar to template
    Block completedBlock = null;
    boolean teamA = false;
    boolean teamB = false;
    
    if(this.blocksTeamA.size() > 0) {
      for(int i=0; i < this.blocksTeamA.size(); i++) {
        for(int j=0; j < this.blockTemplates.size(); j++) {
          if(this.blocksTeamA.size() > i) {
            Block block = this.blocksTeamA.get(i);
            Block template = this.blockTemplates.get(j);
            if(block.similar(template)) {
              this.newTemplate(j);
              this.completedBlocks.add((Block)block);
              completedBlock = block;
              teamA = true;
            }
          }
        }
      }
    }
    
    if(teamA) {
      this.blocksTeamA.remove(completedBlock);
    }
    
    if(this.blocksTeamB.size() > 0) {
      for(int i=0; i < this.blocksTeamB.size(); i++) {
        for(int j=0; j < this.blockTemplates.size(); j++) {
          if(this.blocksTeamB.size() > i) {
            Block block = this.blocksTeamB.get(i);
            Block template = this.blockTemplates.get(j);
            if(block.similar(template)) {
              this.newTemplate(j);
              this.completedBlocks.add((Block)block);
              completedBlock = block;
              teamB = true;
            }
          }
        }
      }
    }
    
    if(teamB) {
      this.blocksTeamB.remove(completedBlock);
    }
  
    //check if completed block in margin, move nomansland if it is  
    if(this.completedBlocks.size() > 0) {
      for(int i=0; i < this.completedBlocks.size(); i++) {
        if(this.completedBlocks.get(i).centroid.x < 0) {
          this.noMansLandPosition -= (int)(width * 0.02);
          this.teamRight.score += 1;
          for(int k=0; k < this.blockTemplates.size(); k++) {
            this.blockTemplates.get(k).translate( -(int)(width * 0.02), 0 );
          }
          this.completedBlocks.remove(i);
        } else if(this.completedBlocks.get(i).centroid.x > width) {
          this.noMansLandPosition += (int)(width * 0.02);
          this.teamLeft.score += 1;
          for(int k=0; k < this.blockTemplates.size(); k++) {
            this.blockTemplates.get(k).translate( +(int)(width * 0.02), 0 );
          }
          this.completedBlocks.remove(i);
        }
      }    
    }
  
    //end game
    if((this.noMansLandPosition > (width * 0.8)) || (this.noMansLandPosition < (width * 0.2))) {
      this.end();
    }
  
  }
  
  void newTemplate(int pos) {
    Block newTemplate = this.blockFactory.createUniqueRandom(this.blockTemplates);
    int templateY = 0;
    switch (pos) {
      case 0:
        templateY = 140;
        break;
      case 1:
        templateY = 400;
        break;
      case 2:
        templateY = height-400;
        break;
      case 3:
        templateY = height-140;
        break;
      default:
    }
    newTemplate.translate(this.noMansLandPosition, templateY);
    this.blockTemplates.set(pos, (Block)newTemplate);
  }
    
}
